#region Imported Namespaces
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Web;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;
using Policy = PHSRAG.Insight21.Policy;
using PHSRAG.Insight21.SearchContext;
using PHSRAG.Security.Enumerations;
using PHSRAG.Insight21.Context;

using AgreementsConstants = PHSRAG.Insight21.InsightUtilities.Constants.AgreementsConstants;
#endregion

namespace PHSRAG.Insight21.InsightWebControls
{
    #region AgreementDetailSubNaviation Class
    /// <summary>
    /// Summary description for AgreementDetailSubNavigation.
    /// </summary>
    [ToolboxData("<{0}:AgreementDetailsSubNavigation runat=server />")]
    [Designer(typeof(AgreementDetailsSubNavigationDesigner), typeof(IDesigner))]
    public class AgreementDetailsSubNavigation : SubNavigation
    {
        #region Constants (Public)
        public const string BudgetDetailCommand = "Budget Details";
        public const string RevenueBreakdownCommand = "Revenue Breakdown";
        public const string ContractDetailCommand = "Contract Details";
        public const string ExpenseDetailCommand = "Expense Details";
        public const string SalaryDetailCommand = "Salary Details";
        public const string ProjectionsCommand = "Projections";
        public const string ProjectDetailCommand = "Project Details";
        public const string LaborDistributionCommand = "Labor Distributions";
        public const string TransactionDetailCommand = "Transaction Details";
        public const string PatientCareDetailCommand = "Patient Care Details";
        public const string agreementIdKey = "agreementIdKey_715A9505-97DF-4685-B3F6-A4B79CD16731";
        #endregion

        #region Constants
        private const string SelectedAgreementDetailsSubNavigationLinkKey = "SelectedAgreementDetailsSubNavigationLink_0C714483-273D-41dd-8608-2009A62477C6";
        #endregion

        #region Instance Variables
        private Policy.ICachePolicy cachePolicy;
        private LinkButton projectDetails;
        private LinkButton laborDistribtion;
        private LinkButton contractDetails;
        private LinkButton salaryDetails;
        private LinkButton transactionDetails;
        private LinkButton budgetDetails;
        private LinkButton revenueBreakdown;
        private LinkButton expenseDetails;
        private LinkButton projections;
        private LinkButton patientCareDetails;
        #endregion

        /// <summary>
        /// Set the selected link so that on load, the appropriate tab may be shown highlighted. This property is invoked
        /// by pages while vectoring to other pages which host this navigation control.
        /// </summary>
        public string SelectedLink
        {
            set { cachePolicy.Cache(SelectedAgreementDetailsSubNavigationLinkKey, value); }
        }

        #region Implementations for virtual methods from Base Class SubNavigation
        /// <summary>
        /// Create all controls in the AgreementDetailsSubNavigation.
        /// </summary>
        protected override void CreateControls()
        {
            Controls.Clear();
            projectDetails = new LinkButton();
            projectDetails.CommandName = projectDetails.Text = ProjectDetailCommand.Replace(" ", Environment.NewLine );
            projectDetails.CommandArgument = GetNavigationKeyValue("SubNavigation.AgreementDetails.ProjectDetailsURL", "");

            //Labor distribution
            UserContext userContext = cachePolicy.GetCachedObject(UserContext.CacheKey) as UserContext;
            if (userContext != null)
            {
                int moduleRoleBitmask = userContext.ModuleRoleBitmask;
                int moduleBitmask = userContext.ModuleBitmask;
                if (((moduleBitmask & (int)ModuleBit.Personnel) != 0 || IsUserAuthorized((int)Security.Enumerations.AccessRightBit.ViewSalaryInformation)))
                {
                    laborDistribtion = new LinkButton();
                    laborDistribtion.CommandName = laborDistribtion.Text = LaborDistributionCommand;
                    laborDistribtion.CommandArgument = GetNavigationKeyValue("SubNavigation.AgreementDetails.LaborDistributionURL", "");
                    
                }
            }

            contractDetails = new LinkButton();
            contractDetails.CommandName = contractDetails.Text = ContractDetailCommand;
            contractDetails.CommandArgument = GetNavigationKeyValue("SubNavigation.AgreementDetails.ContractDetailsURL", "");

            //show salary details link button in design mode or at run time if the user is authorized.
            if (IsDesignMode || IsUserAuthorized((int)Security.Enumerations.AccessRightBit.ViewSalaryInformation))
            {
                salaryDetails = new LinkButton();
                salaryDetails.CommandName = salaryDetails.Text = SalaryDetailCommand;
                salaryDetails.CommandArgument = GetNavigationKeyValue("SubNavigation.Agreements.SalaryOverviewURL", "");
            }

            transactionDetails = new LinkButton();
            transactionDetails.CommandName = transactionDetails.Text = TransactionDetailCommand;
            transactionDetails.CommandArgument = GetNavigationKeyValue("SubNavigation.AgreementDetails.TransactionDetailsURL", "");

            budgetDetails = new LinkButton();
            budgetDetails.CommandName = budgetDetails.Text = BudgetDetailCommand;
            budgetDetails.CommandArgument = GetNavigationKeyValue("SubNavigation.AgreementDetails.BudgetDetailsURL", "");

            revenueBreakdown = new LinkButton();
            revenueBreakdown.CommandName = revenueBreakdown.Text = RevenueBreakdownCommand;
            revenueBreakdown.CommandArgument = GetNavigationKeyValue("SubNavigation.AgreementDetails.RevenueBreakdownURL", "");

            expenseDetails = new LinkButton();
            expenseDetails.CommandName = expenseDetails.Text = ExpenseDetailCommand;
            expenseDetails.CommandArgument = GetNavigationKeyValue("SubNavigation.AgreementDetails.ExpenseDetailsURL", "");

            projections = new LinkButton();
            projections.CommandName = projections.Text = ProjectionsCommand;
            projections.CommandArgument = GetNavigationKeyValue("SubNavigation.AgreementDetails.ProjectionsURL", "");

            if (IsDesignMode || IsUserAuthorized((int)Security.Enumerations.AccessRightBit.ViewPatientCareDetails))
            {
                patientCareDetails = new LinkButton();
                patientCareDetails.CommandName = patientCareDetails.Text = PatientCareDetailCommand;
                patientCareDetails.CommandArgument = GetNavigationKeyValue("SubNavigation.AgreementDetails.PatientCareDetailsURL", "");
            }
        }

        /// <summary>
        /// Setup the control tree to reflect the actual (and exact) layout of the controls within the AgreementDetailsSubNavigation.
        /// If no fund number was supplied hide all the detail tabs except for project and contract details 
        /// Can be loaded without a fund number 
        /// </summary>
        protected override void GenerateControlTree()
        {
            Hashtable incomingHashTable = (Hashtable)cachePolicy.GetCachedObject(AgreementsConstants.AgreementDetailsKey);

            Table table = new Table();
            //table.BorderColor = System.Drawing.Color.Red;
            table.EnableViewState = false;
            table.CssClass = "SubModuleOverviewNavigation";
            Controls.Add(table);

            TableRow row = new TableRow();
            table.Rows.Add(row);

            TableCell cell = new TableCell();
            row.Cells.Add(cell);
            cell.CssClass = "SubModuleOverviewNavigationSmallFillerCell";
            cell.Controls.Add(new LiteralControl("&nbsp;"));

            int fundId = (incomingHashTable == null) ? 0 :
                ((incomingHashTable["fundIdKey_06AB2FD7-D783-4d8e-AC5E-2119C71AF9A4"] == null) ? 0 : (int)incomingHashTable["fundIdKey_06AB2FD7-D783-4d8e-AC5E-2119C71AF9A4"]);

            string fundNumber = (incomingHashTable == null) ? string.Empty :
                ((incomingHashTable["fundNumberKey_06AB2FD7-D783-4d8e-AC5E-2119C71AF9A4"] == null) ? string.Empty : (string)incomingHashTable["fundNumberKey_06AB2FD7-D783-4d8e-AC5E-2119C71AF9A4"]);

            if ((fundId == 0) &&
                (String.IsNullOrEmpty(fundNumber) || fundNumber == "0"))
            {
                //there is no fund info so format the table with the 
                //spaces and only adding non fund related link buttons to the 
                //table row.
                cell = new TableCell();
                row.Cells.Add(cell);

                table = new Table();
                cell.Controls.Add(table);

                row = new TableRow();
                table.Rows.Add(row);

                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(projectDetails);

                cell = new TableCell();
                row.Cells.Add(cell);

                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(contractDetails);

            }
            else
            {
                //there is fund info so add link buttons related to funds to table row
                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(projectDetails);

               
                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(contractDetails);


                if (salaryDetails != null)
                {
                    cell = new TableCell();
                    row.Cells.Add(cell);
                    cell.Controls.Add(salaryDetails);
                }
                if (laborDistribtion != null)
                {
                    cell = new TableCell();
                    row.Cells.Add(cell);
                    cell.Controls.Add(laborDistribtion);
                }
                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(transactionDetails);

                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(budgetDetails);

                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(revenueBreakdown);

                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(expenseDetails);

                if (patientCareDetails != null)
                {
                    cell = new TableCell();
                    row.Cells.Add(cell);
                    cell.Controls.Add(patientCareDetails);
                }

                cell = new TableCell();
                row.Cells.Add(cell);
                cell.Controls.Add(projections);
            }

            CreateSelectedLinkAdornments(row);
        }

        /// <summary>
        /// Retrieve the name of the link that was last clicked on.
        /// </summary>
        /// <returns>Reference to the link button corresponding to the clicked link</returns>
        protected override LinkButton GetSelectedLink()
        {
            if (IsDesignMode)
                return projectDetails;

            // Anytime a link is clicked on, the OnBubbleEvent handler stores the name of the link in the session. Retrieve
            // that name and return the corresponding link button reference.

            object o = cachePolicy.GetCachedObject(SelectedAgreementDetailsSubNavigationLinkKey);
            if (o != null)
            {
                string commandName = (string)o;
                System.Diagnostics.Trace.WriteLine(string.Format("{0}: {1}", DateTime.Now, commandName));
                if (commandName == projectDetails.CommandName)
                    return projectDetails;
                if (commandName == contractDetails.CommandName)
                    return contractDetails;
                if (salaryDetails != null && commandName == salaryDetails.CommandName)
                    return salaryDetails;
                if (laborDistribtion != null && commandName == laborDistribtion.CommandName)                                
                    return laborDistribtion;
                if (commandName == transactionDetails.CommandName)
                    return transactionDetails;
                if (commandName == budgetDetails.CommandName)
                    return budgetDetails;
                if (commandName == revenueBreakdown.CommandName)
                    return revenueBreakdown;
                if (commandName == expenseDetails.CommandName)
                    return expenseDetails;
                if (commandName == projections.CommandName)
                    return projections;
                if (patientCareDetails != null && commandName == patientCareDetails.CommandName)
                    return patientCareDetails;
            }
            return projectDetails;
        }

        protected override void ManageSelection(string commandName)
        {
            base.ManageSelection(commandName);

            CommonSearchContext searchContext = (CommonSearchContext)cachePolicy.GetCachedObject(CommonSearchContext.CacheKey);
            searchContext.CurrentLevel = SearchCriteria.Level.Detail;
        }

        /// <summary>
        /// Handler for the event raised when the page is being initialized.
        /// Retrieve the cache policy and page cache policy in force.
        /// </summary>
        /// <param name="e">Argument associated with the event</param>
        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (!IsDesignMode)
                cachePolicy = (Policy.ICachePolicy)Page.Session[Policy.Names.CachePolicyKey];
        }

        /// <summary>
        /// Gets the key used to store the SelectedSubNavigationLink information in any hash table. 
        /// </summary>
        protected override string SelectedSubNavigationLinkKey
        {
            get
            {
                return SelectedAgreementDetailsSubNavigationLinkKey;
            }
        }
        #endregion

        #region Private Methods
        private void CreateSelectedLinkAdornments(TableRow row)
        {
            LinkButton selectedLink = GetSelectedLink();
            foreach (TableCell cell in row.Cells)
            {
                if ((cell.Controls.Count == 1) && (cell.Controls[0] == selectedLink))
                {
                    cell.CssClass = "SubModuleNavigationSelectedOverview";

                    TableCell adornmentCell = new TableCell();
                    adornmentCell.CssClass = "SubModuleNavigationSelectedOverviewAdornment";
                    row.Cells.AddAt(row.Cells.GetCellIndex(cell), adornmentCell);

                    const string prefixImage = "../Images/Row3_Left.gif";
                    Image image = new Image();
                    image.ImageUrl = prefixImage;
                    if (!IsDesignMode)
                        adornmentCell.Width = (new System.Drawing.Bitmap(Context.Server.MapPath(prefixImage))).Width;
                    adornmentCell.Controls.Add(image);

                    adornmentCell = new TableCell();
                    adornmentCell.CssClass = "SubModuleNavigationSelectedOverviewAdornment";
                    row.Cells.AddAt(row.Cells.GetCellIndex(cell) + 1, adornmentCell);

                    const string suffixImage = "../Images/Row3_Right.gif";
                    image = new System.Web.UI.WebControls.Image();
                    image.ImageUrl = suffixImage;
                    if (!IsDesignMode)
                        adornmentCell.Width = (new System.Drawing.Bitmap(Context.Server.MapPath(suffixImage))).Width;
                    adornmentCell.Controls.Add(image);

                    break;
                }
            }
        }

        private static string GetNavigationKeyValue(string key, string defaultValue)
        {
            return IsDesignMode ? defaultValue : Utility.Settings.GetKeyValue(key, defaultValue);
        }

        private bool IsUserAuthorized(int accessRight)
        {
            bool isPI = false;
            Hashtable h = cachePolicy.GetCachedObject(AgreementsConstants.AgreementDetailsKey) as Hashtable;
            // This control is loaded on some overview pages, even when not looking at details
            if (h == null) return false;
            if (accessRight == (int)Security.Enumerations.AccessRightBit.ViewPatientCareDetails
                || accessRight == (int)Security.Enumerations.AccessRightBit.ViewSalaryInformation)
            {
                UserContext context = (UserContext)cachePolicy.GetCachedObject(PHSRAG.Insight21.Context.UserContext.CacheKey);
                int agreementId = Convert.ToInt32(h[agreementIdKey]);
                Agreements.Agreement agreement = new Agreements.Agreement(cachePolicy);
                agreement.Load(Utility.DataAccess.ConnectionString, agreementId);
                isPI = (context.DomainUserId == agreement.PIID);
            }
            int accessRights = (h[AgreementsConstants.AccessRightsKey] != null) ? Convert.ToInt32(h[AgreementsConstants.AccessRightsKey]) : 0;
            return isPI || ((accessRights & accessRight) != 0);
        }
        #endregion

        #region Private Properties
        /// <summary>
        /// Return true if the control is in design mode.
        /// </summary>
        private static bool IsDesignMode
        {
            get { return HttpContext.Current == null; }
        }
        #endregion
    }
    #endregion

    #region AgreementDetailsSubNavigationDesigner Class
    /// <summary>
    /// Designer associated with the control.
    /// </summary>
    public class AgreementDetailsSubNavigationDesigner : ControlDesigner
    {
        #region Overrides
        /// <summary>
        /// Force the control to create its child controls for display at design time.
        /// </summary>
        /// <returns>HTML representation of the control</returns>
        public override string GetDesignTimeHtml()
        {
            ((AgreementDetailsSubNavigation)Component).Design();
            return base.GetDesignTimeHtml();
        }
        #endregion
    }
    #endregion
}
